﻿@page "/scheduler/fare-calendar"

@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.Schedule
@using Syncfusion.Blazor.Navigations
@inherits SampleBaseComponent;

<SampleDescription>
    <p>
        This demo illustrates how to customize the scheduler to showcase it as an
        <strong>Airfare calendar</strong> depicting the lowest available price on each day of a month for a specific route, say between
        Barcelona and Los Angeles.
    </p>
</SampleDescription>
<ActionDescription>
    <p>
        In this demo, Scheduler initially displays the fare of the airline service which offers lowest price on each day by comparing
        between the 3 available airlines. Here, the 3 airline services acts as the Scheduler resources. Appointment collection
        has been dynamically generated for a month (for all the 3 resources) within the
        <code>GenerateEvents</code> method and then filtered externally based on the ascending Fare value within the
        <code>FilterByFare</code> method. Since each day of the Scheduler needs to display only a single appointment showing the fare value, it has been queried to take only the first 30 values from the sorted list and assigned it to the Scheduler
        <code>DataSource</code>. Here, the filtering process needs to be carried in
        <code>OnInitialized</code> method and therefore, the dataSource of Scheduler is assigned within this method.
    </p>
    <p>
        Scheduler has been rendered in a readonly mode and therefore no editing actions are allowed here. To customize the look of
        the appointments that displays the fare value,
        <code>EventTemplate</code> option within the
        <code>ScheduleView</code> tag is being used. Also, the tooltip has been enabled with
        <code>TooltipTemplate</code> option to display the flight details in a customized style.
    </p>
</ActionDescription>

<div class="col-lg-9 control-section">
    <div class="content-wrapper">
        <div class="schedule-demo-heading">
            Cheapest one way fares from Barcelona to Los Angeles
        </div>
        <SfToolbar>
            <ToolbarItems>
                <ToolbarItem Align="ItemAlign.Center" Text="@(CurrentDate.ToString("MMMM yyyy"))"></ToolbarItem>
            </ToolbarItems>
        </SfToolbar>
        <SfSchedule @ref="@ScheduleObj" TValue="EventData" Width="100%" Height="650px" @bind-SelectedDate="@CurrentDate" ShowHeaderBar="false" Readonly="true">
            <ScheduleResources>
                <ScheduleResource TValue="int[]" TItem="AirlinesData" DataSource="@AirlineData" Field="AirlineId" Title="Airline" Name="Airlines" TextField="Text" IdField="Id" AllowMultiple="true"></ScheduleResource>
            </ScheduleResources>
            <ScheduleViews>
                <ScheduleView Option="View.Month">
                    <CellHeaderTemplate>
                        @{
                            @(((context as TemplateContext).Date.Day == 1 && (context as TemplateContext).Date == DateTime.Today.Date) ? (context as TemplateContext).Date.ToString("MMM d") : (context as TemplateContext).Date.ToString("dd"));
                            if ((context as TemplateContext).Date == LowestFareDate.Date && DataSource.Count != 0)
                            {
                                <span class="best-price">Best Price</span>
                            }
                        }
                    </CellHeaderTemplate>
                    <EventTemplate>
                        @{
                            <div class="template-wrap">
                                <div class="fare-detail">$@((context as EventData).Fare)</div>
                                <div class="airline-name" style="display:flex;padding-left:5px;">
                                    <div class="airline-logo + @getAirWaysImage((context as EventData).AirlineId)"></div>
                                    <div class="airway-name">@(getAirWaysName((context as EventData).AirlineId))</div>
                                </div>
                            </div>
                        }
                    </EventTemplate>
                </ScheduleView>
            </ScheduleViews>
            <ScheduleEvents TValue="EventData" OnPopupOpen="@OnPopupOpen"></ScheduleEvents>
            <ScheduleEventSettings DataSource="@DataSource" EnableTooltip="true">
                <TooltipTemplate>
                    @{
                        <div class="event-tooltip">
                            <div class="airline-header">
                                <div class="airline-logo + @getAirWaysImage((context as EventData).AirlineId)"></div>
                                <div class='airline-name'>@(getAirWaysName((context as EventData).AirlineId))</div>
                            </div>
                            <div class='airline-details text-size'>
                                <div class='airline-title'>Fare Details:</div>
                                <div class='airline-fare'>$@((context as EventData).Fare) per person</div>
                            </div>
                            <div class='airline-flex-row text-size'>
                                <div class='airline-flex-col airline-title border-right'>Arrival</div>
                                <div class='airline-flex-col airline-title text-right'>Depature</div>
                            </div>
                            <div class='airline-flex-row text-size'>
                                <div class='airline-flex-col border-right'>@(getFormattedTime((context as EventData).StartTime))</div>
                                <div class='airline-flex-col margin-right text-right'>@(getFormattedTime((context as EventData).EndTime))</div>
                            </div>
                        </div>
                    }
                </TooltipTemplate>
            </ScheduleEventSettings>
        </SfSchedule>
    </div>
</div>
<div class="col-lg-3 property-section">
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>
    <div class="property-panel-section">
        <div class="property-panel-header">Properties</div>
        <div class="property-panel-content">
            <table id='property' title='Properties' class='property-panel-table' style="width: 100%;">
                <tbody>
                    <tr style="height: 50px">
                        <td style="width: 100%">
                            <SfCheckBox TChecked="bool" @bind-Checked="@Airways1Checked" Label="Airways 1" Value="@Airways1" ValueChange="@OnChange" CssClass="e-resource e-airways-1"></SfCheckBox>
                        </td>
                    </tr>
                    <tr style="height: 50px">
                        <td style="width: 100%">
                            <SfCheckBox TChecked="bool" @bind-Checked="@Airways2Checked" Label="Airways 2" Value="@Airways2" ValueChange="@OnChange" CssClass="e-resource e-airways-2"></SfCheckBox>
                        </td>
                    </tr>
                    <tr style="height: 50px">
                        <td style="width: 100%">
                            <SfCheckBox TChecked="bool" @bind-Checked="@Airways3Checked" Label="Airways 3" Value="@Airways3" ValueChange="@OnChange" CssClass="e-resource e-airways-3"></SfCheckBox>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

@code{
    SfSchedule<EventData> ScheduleObj;
    public DateTime CurrentDate { get; set; } = new DateTime(2020, 3, 1);
    public DateTime LowestFareDate { get; set; }
    public bool Airways1Checked { get; set; } = true;
    public bool Airways2Checked { get; set; } = true;
    public bool Airways3Checked { get; set; } = true;

    public string Airways1 { get; set; } = "1";
    public string Airways2 { get; set; } = "2";
    public string Airways3 { get; set; } = "3";

    List<EventData> DataSource = new List<EventData>();
    List<EventData> EventCollections = new List<EventData>();
    List<AirlinesData> AirlineData = new List<AirlinesData>
    {
        new AirlinesData { Id = 1, Text = "Airways 1"},
        new AirlinesData { Id = 2, Text = "Airways 2"},
        new AirlinesData { Id = 3, Text = "Airways 3"}
    };

    private string getAirWaysName(int airlineId)
    {
        return (airlineId == 1) ? "Airways 1" : (airlineId == 2) ? "Airways 2" : "Airways 3";
    }

    private string getAirWaysImage(int airlineId)
    {
        return (airlineId == 1) ? "airways-1" : (airlineId == 2) ? "airways-2" : "airways-3";
    }

    private string getFormattedTime(DateTime date)
    {
        return date.ToString("HH:mm");
    }

    public void OnChange(ChangeEventArgs<bool> args)
    {
        List<int> selectedResource = new List<int>();
        List<EventData> filteredData = new List<EventData>();
        if (Airways1Checked) { selectedResource.Add(0); }
        if (Airways2Checked) { selectedResource.Add(1); }
        if (Airways3Checked) { selectedResource.Add(2); }
        foreach (int resource in selectedResource)
        {
            List<EventData> data = EventCollections.Where(x => AirlineData[resource].Id == x.AirlineId).ToList();
            filteredData = filteredData.Concat(data).ToList();
        }
        DataSource = filteredData = FilterByFare(filteredData);
    }

    public void OnPopupOpen(PopupOpenEventArgs<EventData> args)
    {
        args.Cancel = true;
    }

    public List<EventData> GenerateEvents()
    {
        List<EventData> collections = new List<EventData>();
        List<EventData> dataCollections = new List<EventData>
        {
            new EventData { Id = 100, StartTime = new DateTime(2020, 3, 1, 8, 30, 0), EndTime = new DateTime(2020, 3, 1, 10, 0, 0), AirlineId = 1 },
            new EventData { Id = 102, StartTime = new DateTime(2020, 3, 1, 11, 0, 0), EndTime = new DateTime(2020, 3, 1, 12, 0, 0), AirlineId = 2 },
            new EventData { Id = 103, StartTime = new DateTime(2020, 3, 1, 14, 0, 0), EndTime = new DateTime(2020, 3, 1, 15, 0, 0), AirlineId = 3 }
        };
        DateTime start = new DateTime(2020, 3, 1);
        List<DateTime> dateCollections = new List<DateTime>();
        int DaysCountInMonth = DateTime.DaysInMonth(CurrentDate.Year, CurrentDate.Month);
        int id = 1;
        int day = 0;
        for (int date = 0; date < DaysCountInMonth; date++)
        {
            int resource = 1;
            foreach (EventData data in dataCollections)
            {
                collections.Add(new EventData
                {
                    Id = id,
                    StartTime = data.StartTime.AddDays(day),
                    EndTime = data.EndTime.AddDays(day),
                    AirlineId = resource,
                    Fare = Convert.ToDouble(((new Random().NextDouble() * 500) + 100).ToString("n2"))
                });
                resource += 1;
                id += 1;
            }
            day += 1;
        }
        EventCollections = collections;
        List<EventData> filterCollection = FilterByFare(collections);
        return filterCollection;
    }

    public List<EventData> FilterByFare(List<EventData> appointments)
    {
        List<EventData> finalData = new List<EventData>();
        if (appointments.Count == 0) { return finalData; }
        var renderDate = appointments.GroupBy(x => x.StartTime.Date).ToList();
        foreach (var date in renderDate)
        {
            DateTime strTime = date.Key;
            DateTime endTime = new DateTime(strTime.Year, strTime.Month, strTime.Day, 23, 59, 59, 59);
            var predicate = from app in appointments
                            where app.StartTime >= strTime && app.EndTime >= app.StartTime && app.StartTime < endTime || app.StartTime <= strTime && app.EndTime > strTime
                            select app;
            List<EventData> perDayData = predicate.ToList();
            if (perDayData.Count > 0)
            {
                perDayData = perDayData.OrderBy(x => x.Fare).ToList();
                finalData.Add(perDayData.First());
            }
        }
        LowestFareDate = finalData.OrderBy(x => x.Fare).First().StartTime;
        return finalData;
    }

    protected override void OnInitialized()
    {
        DataSource = GenerateEvents();
    }

    public class EventData
    {
        public int Id { get; set; }
        public string Subject { get; set; }
        public string Location { get; set; }
        public string Description { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public Nullable<bool> IsAllDay { get; set; }
        public string CategoryColor { get; set; }
        public string RecurrenceRule { get; set; }
        public Nullable<int> RecurrenceID { get; set; }
        public string RecurrenceException { get; set; }
        public string StartTimezone { get; set; }
        public string EndTimezone { get; set; }
        public int AirlineId { get; set; }
        public double Fare { get; set; }
    }

    public class AirlinesData
    {
        public int Id { get; set; }
        public string Text { get; set; }
    }
}

<style>
    .e-tooltip-wrap.e-schedule-event-tooltip .airline-flex-row {
        display: flex;
        padding: 0 5px;
        line-height: 20px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .airline-flex-col {
        flex: 0 0 50%;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .text-right {
        text-align: right;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .margin-right {
        margin-left: -21px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .text-size {
        font-size: 14px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .border-right {
        border-right: 1px solid #fff;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .airline-fare {
        padding-left: 8px;
    }

    .e-schedule .e-appointment .template-wrap {
        color: black;
        width: 100%;
    }

    .highcontrast .e-schedule .e-appointment .template-wrap,
    .highcontrast .e-schedule .best-price:not(.e-work-cells) {
        color: #fff;
    }

    .e-schedule .best-price:not(.e-work-cells) {
        color: #1A961A;
        float: right;
        margin-left: 5px;
        width: auto;
        font-size: 12px;
    }

    .highcontrast .e-schedule .best-price:not(.e-work-cells) {
        color: #33DB33;
    }

    .e-schedule.e-device .best-price:not(.e-work-cells) {
        display: none;
    }

    .schedule-demo-heading {
        font-size: 16px;
        padding-bottom: 15px;
        text-align: center;
        font-weight: 500
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .event-tooltip {
        width: 217px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .airline {
        width: 40%;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .event-tooltip .airline-header {
        display: flex;
        padding: 8px 0px 8px 0px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .event-tooltip .airline-details {
        display: flex;
        padding: 8px 5px 8px 5px;
    }

    .e-tooltip-wrap.e-schedule-event-tooltip .event-tooltip .airline-timings,
    .e-tooltip-wrap.e-schedule-event-tooltip .event-tooltip .airline-timings-title {
        display: flex;
        padding: 5px;
    }

    .e-schedule-event-tooltip .event-tooltip .airline-header {
        border-bottom: 1px solid #e0e0e0;
    }

    .e-schedule-event-tooltip .event-tooltip .airline-logo,
    .e-schedule .template-wrap .airline-logo {
        background-size: cover;
        background-repeat: no-repeat;
        margin-top: -3px;
        width: 25px;
        height: 25px;
    }

    .e-schedule-event-tooltip .event-tooltip .airline-logo.airways-1,
    .e-schedule .template-wrap .airline-logo.airways-1 {
        background-image: url('https://ej2.syncfusion.com/demos/src/schedule/images/airways-1.svg');
    }

    .e-schedule-event-tooltip .event-tooltip .airline-logo.airways-2,
    .e-schedule .template-wrap .airline-logo.airways-2 {
        background-image: url('https://ej2.syncfusion.com/demos/src/schedule/images/airways-2.svg');
    }

    .e-schedule-event-tooltip .event-tooltip .airline-logo.airways-3,
    .e-schedule .template-wrap .airline-logo.airways-3 {
        background-image: url('https://ej2.syncfusion.com/demos/src/schedule/images/airways-3.svg');
    }

    .e-schedule .fare-detail {
        color: #00837B;
        font-size: 16px;
        font-weight: 500;
        height: 25px;
        padding-left: 5px;
    }

    .highcontrast .e-schedule .fare-detail {
        color: #1B96BB;
    }

    .e-schedule.e-device .fare-detail {
        font-size: 11px;
    }

    .e-schedule .airway-name {
        font-size: 12px;
        overflow: hidden;
        padding-left: 5px;
        text-overflow: ellipsis;
    }

    .e-schedule.e-device .airway-name {
        display: none;
    }

    .e-schedule .e-month-view .e-appointment {
        height: 45px;
        background: none;
        border-width: 0;
        margin-top: 10px;
    }

    .e-schedule.e-device .e-month-view .e-appointment {
        height: 45px;
    }

    .e-bigger .e-schedule .e-month-view .e-appointment {
        height: 40px;
    }

    .e-schedule .e-month-view .e-appointment .e-appointment-details {
        height: inherit;
    }

    .e-schedule .e-month-view .e-more-indicator {
        display: none
    }

    .e-schedule .e-month-view .e-appointment.e-appointment-border,
    .e-schedule .e-month-view .e-appointment:focus {
        border-width: 0;
    }

    .e-tooltip-wrap.e-popup.e-schedule-event-tooltip {
        opacity: 1;
    }

    .highcontrast .e-tooltip-wrap.e-popup.e-schedule-event-tooltip {
        border-color: #e0e0e0;
        background-color: #fff;
    }

    .highcontrast .e-tooltip-wrap.e-popup.e-schedule-event-tooltip .e-tip-content {
        color: #000;
    }

    .e-tooltip-wrap.e-popup.e-schedule-event-tooltip .event-tooltip .airline-name {
        font-weight: 500;
        font-size: 16px;
        padding-left: 10px;
        padding-top: 3px;
    }

    .e-tooltip-wrap.e-popup.e-schedule-event-tooltip .event-tooltip .airline-title {
        font-weight: 500;
        font-size: 14px;
    }

    .e-tooltip-wrap.e-popup.e-schedule-event-tooltip .event-tooltip .airline-logo {
        margin-left: 5px;
        background-size: 25px;
        height: 25px;
        width: 25px;
        margin-top: 0px;
    }

    .property-panel-content .e-checkbox-wrapper.e-resource.e-airways-1 .e-frame {
        background-color: #EA7A57;
        border-color: transparent;
    }

    .property-panel-content .e-checkbox-wrapper.e-resource.e-airways-2 .e-frame {
        background-color: #357CD2;
        border-color: transparent;
    }

    .property-panel-content .e-checkbox-wrapper.e-resource.e-airways-3 .e-frame {
        background-color: #7FA900;
        border-color: transparent;
    }

    @@media (max-width: 550px) {
        .schedule-demo-heading {
            font-size: 14px;
        }
    }
</style>